package com.wenlin.myproduction.widget;

import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.DecelerateInterpolator;

import androidx.annotation.Nullable;

import com.wenlin.myproduction.R;


/**
 * @author cwl
 * @desc 彩色进度条
 * @Email 377979485@qq.com
 * @time 2023/10/26/026 15:05
 */
public class ColorProgressView extends View {
    private static final float SCALE_RATIO = 0.85f;//缩放比例
    private final int marHor = (int) dpToPx(8 * SCALE_RATIO);
    private final int marTop = (int) dpToPx(5 * SCALE_RATIO);
    private Paint paint, paintMask;
    private Path path;
    private RectF rectF;
    private Bitmap bitmapBg, bitmapBar;
    private int viewWidth = (int) dpToPx(210.5f * SCALE_RATIO);
    private int viewHeight = (int) dpToPx(30f * SCALE_RATIO);
    private float barWidth = dpToPx(194 * SCALE_RATIO);
    private float barHeight = dpToPx(19 * SCALE_RATIO);
    private final int barTotalWidth = viewWidth - marHor * 2 - (int) barHeight;
    private int progress;
    private PorterDuffXfermode porterDuffXfermode;
    private float barEndX = marHor + barHeight / 2f;
    private float valueX = barEndX;
    private ValueAnimator valueAnimator;
    private boolean showMask;
    private boolean isGreen;//

    public ColorProgressView(Context context) {
        this(context, null);
    }

    public ColorProgressView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ColorProgressView);
        if (typedArray != null) {
            isGreen = typedArray.getBoolean(R.styleable.ColorProgressView_cpv_is_green, false);
            typedArray.recycle();
            typedArray = null;
        }
        init();
    }

    private void init() {
        paint = new Paint();
        paint.setStyle(Paint.Style.FILL_AND_STROKE);
        paint.setAntiAlias(true);
        paint.setDither(true);

        paintMask = new Paint();
        paintMask.setStyle(Paint.Style.FILL_AND_STROKE);
        paintMask.setAntiAlias(true);
        paintMask.setDither(true);
        paintMask.setColor(Color.parseColor("#60000000"));

        path = new Path();
        rectF = new RectF();

        //裁剪模式
        porterDuffXfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);//模式：显示前景图并取交集（IN）。（SRC source表示源图片，背景图是DST destination目的地）

        bitmapBg = BitmapFactory.decodeResource(getResources(), R.mipmap.common_bg_progress_bar);
        bitmapBar = BitmapFactory.decodeResource(getResources(), isGreen ? R.mipmap.common_icon_green_progress_bar : R.mipmap.common_icon_yellow_progress_bar);
        bitmapBg = getBitmapWithTargetWidthHeight(bitmapBg, viewWidth, viewHeight);
        bitmapBar = getBitmapWithTargetWidthHeight(bitmapBar, barWidth, barHeight);

        //fake data
//        progress = 55;
//        barEndX = marHor + barHeight / 2f + barTotalWidth * (progress / 100f);
//        valueX = barEndX;
    }

    public void setProgress(int p) {
        if (p > 100) p = 100;
        if (p < 0) p = 0;
        progress = p;
        barEndX = marHor + barHeight / 2f + barTotalWidth * (progress / 100f);
        startAnimation();
        invalidate();
    }

    public void setShowMask(boolean showMask) {
        this.showMask = showMask;
        invalidate();
    }

    private void startAnimation() {
        if (valueAnimator != null && valueAnimator.isRunning()) {
            valueAnimator.cancel();
            valueAnimator = null;
        }
        valueAnimator = ValueAnimator.ofFloat(valueX, barEndX);
        valueAnimator.addUpdateListener(animation -> {
            valueX = (float) animation.getAnimatedValue();
            invalidate();
        });
        valueAnimator.setDuration(500);
        valueAnimator.setInterpolator(new DecelerateInterpolator());
        valueAnimator.start();
    }

    /**
     * 生成新的Bitmap图片
     *
     * @return 所求
     */
    private Bitmap getBitmapWithTargetWidthHeight(Bitmap bitmap, float newWidth, float newHeight) {
        Matrix matrix = new Matrix();
        int width = bitmap.getWidth();//获取图片本身的宽
        int height = bitmap.getHeight();//获取图片本身的高
        float scaleRatioOfWidth = newWidth / (width > 0 ? width : newWidth);//宽度缩放比
        float scaleRatioOfHeight = newHeight / (height > 0 ? height : newHeight);//高度缩放比
        matrix.postScale(scaleRatioOfWidth, scaleRatioOfHeight);
        return Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (bitmapBg != null) canvas.drawBitmap(bitmapBg, 0, 0, paint);
        if (bitmapBar != null && progress > 0) {
            canvas.save();
            path.reset();
            path.moveTo(marHor + barHeight / 2f, marTop);
            path.lineTo(valueX, marTop);
            rectF.set(valueX - barHeight / 2f, marTop, valueX + barHeight / 2f, marTop + barHeight);
            path.arcTo(rectF, -90, 180);
            path.lineTo(marHor + barHeight / 2f, marTop + barHeight);
            rectF.set(marHor, marTop, marHor + barHeight, marTop + barHeight);
            path.arcTo(rectF, 90, 180);
            path.close();
            canvas.drawPath(path, paint);
            canvas.saveLayerAlpha(marHor,
                    marTop,
                    valueX + barHeight / 2f,
                    marTop + barHeight, 255);
            canvas.drawPath(path, paint);
            paint.setXfermode(porterDuffXfermode);
            canvas.drawBitmap(bitmapBar, marHor, marTop, paint);
            paint.setXfermode(null);
            canvas.restore();
        }
        if (showMask)
            canvas.drawRoundRect(0, 0, viewWidth, viewHeight, viewHeight / 2f, viewHeight / 2f, paintMask);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (bitmapBg != null && !bitmapBg.isRecycled()) {
            bitmapBg.recycle();
            bitmapBg = null;
        }
        if (bitmapBar != null && !bitmapBar.isRecycled()) {
            bitmapBar.recycle();
            bitmapBar = null;
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(measure(widthMeasureSpec, true), measure(heightMeasureSpec, false));
    }

    /**
     * 获取宽或者高
     *
     * @param measureSpec 测量单位
     * @param isWidSpec   是宽还是高
     * @return 所求
     */
    private int measure(int measureSpec, boolean isWidSpec) {
        int result;
        int mode = MeasureSpec.getMode(measureSpec);
        int size = MeasureSpec.getSize(measureSpec);
        if (mode == MeasureSpec.EXACTLY) {
            result = size;
        } else {
            result = isWidSpec ? viewWidth : viewHeight;
            if (mode == MeasureSpec.AT_MOST) result = Math.min(result, size);
        }
        return result;
    }

    /**
     * 转化长度单位
     *
     * @param dp dp长度
     * @return 对应的px长度
     */
    private float dpToPx(float dp) {
        float scale = getResources().getDisplayMetrics().density;
        return dp * scale;
    }
}
